#include "qwidgetview.h"

#include "../../sharedLib/qabstracthost.h"
#include "../../sharedLib/qprojectcore.h"
#include "../../sharedLib/qwidgetplugin.h"
#include "../../sharedLib/pluginloader.h"

#include <QItemDelegate>
#include <QPainter>
#include <QHeaderView>
#include <QIcon>
#include <QApplication>
#include <QVBoxLayout>

using namespace CORELIB;

namespace CORELIB
{

    class QObjectDelegate: public QItemDelegate
    {
    public :
        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
        QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
    };

}

void QObjectDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItemV3 opt=option;
    QColor c;
    c=QColor(255,191,239);
    if(opt.features & QStyleOptionViewItemV2::Alternate)
    {
        c=c.lighter(112);
    }

    painter->fillRect(option.rect,c);
    opt.state &=~ QStyle::State_HasFocus;
    QItemDelegate::paint(painter,opt,index);
    opt.palette.setCurrentColorGroup(QPalette::Active);
    QColor color=static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor,&opt));
    painter->setPen(color);

    if(index.column()==0)
    {
        int right=option.direction==Qt::LeftToRight?option.rect.right():option.rect.left();
        painter->drawLine(right,option.rect.y(),right,option.rect.bottom());
    }
}

QSize QObjectDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QSize sz=QItemDelegate::sizeHint(option,index);
    sz.setHeight(20);
    return sz;
}

QWidgetView::QWidgetView(SHAREDLIB::QAbstractHost *host, QWidget *parent) :
    QTreeWidget(parent),
    m_property_host(host)
{
    setFrameStyle(QFrame::NoFrame);
    setAlternatingRowColors(true);
    setEditTriggers(QAbstractItemView::EditKeyPressed);
    setItemDelegate(new QObjectDelegate);
    header()->hide();

    connect(this,SIGNAL(itemClicked(QTreeWidgetItem*,int)),this,SLOT(clickedItem(QTreeWidgetItem*,int)));


    QPalette p=this->palette();
    p.setColor(QPalette::Inactive,QPalette::Highlight,p.color(QPalette::Active,QPalette::Highlight));
    p.setColor(QPalette::Inactive,QPalette::HighlightedText,p.color(QPalette::Active,QPalette::HighlightedText));
    this->setPalette(p);

    initWidgetList();
}

void QWidgetView::initWidgetList()
{
    SHAREDLIB::QAbstractHost* root=SHAREDLIB::QProjectCore::getCore()->host();

    QList<SHAREDLIB::QAbstractHost*>   list=root->getChildren();

    QTreeWidgetItem *item=new QTreeWidgetItem(this);
    item->setText(0,tr("global"));
    m_items.insert(root,item);

    SHAREDLIB::QAbstractHost* host;

    QMap<QString,SHAREDLIB::QWidgetPlugin*> plugins=SHAREDLIB::PluginLoader::getPluginLoader()->getWidgetPlugins();

    QObject *obj;
    SHAREDLIB::QWidgetPlugin *plugin;
    QString type=m_property_host->get_type();
    while(list.size()>0)
    {
        host=list.first();
        list.removeFirst();
        if(type!="" && host->get_type()!=type)
        {
            continue;
        }
        obj=host->object();
        QTreeWidgetItem *par=m_items.value(host->getParent());
        item=new QTreeWidgetItem(par);
        item->setText(0,obj->property("objectName").toString());
        QString type=obj->property("type").toString();
        QString pluginName=obj->property("plugin").toString();
        plugin=plugins.value(pluginName);
        if(plugin!=NULL)
        {
            SHAREDLIB::WidgetInfo info=plugin->widgetInfo(type);
            item->setIcon(0,QIcon(info.m_icon));
        }
        else
        {
            foreach(SHAREDLIB::QWidgetPlugin *plugin,plugins)
            {
                if(plugin->supportWidgets().contains(type))
                {
                    item->setIcon(0,QIcon(plugin->widgetInfo(type).m_icon));
                    break;
                }
            }
        }
        m_items.insert(host,item);
        list+=host->getChildren();
    }
    this->expandAll();
}

void QWidgetView::clickedItem(QTreeWidgetItem *item,int)
{
    QMapIterator<SHAREDLIB::QAbstractHost*,QTreeWidgetItem*>   it(m_items);

    while(it.hasNext())
    {
        it.next();
        if(it.value()==item)
        {
            emit select(it.key());
            return;
        }
    }
}

void QWidgetView::findNext(const QString &text)
{
     QList<QTreeWidgetItem*> items=selectedItems();
     QTreeWidgetItem    *item;
     if(items.size()>0)
     {
        item=items.first();
     }
     else
     {
        item=m_items.value(SHAREDLIB::QProjectCore::getCore()->host());
        if(item->text(0).indexOf(text)>=0)
        {
            setSelected(item);
            return;
        }
     }
     find(item,item,text,FP_NEXT);
}

void QWidgetView::findPrev(const QString &text)
{
    QList<QTreeWidgetItem*> items=selectedItems();
    QTreeWidgetItem    *item;
    if(items.size()>0)
    {
       item=items.first();
    }
    else
    {
       item=m_items.value(SHAREDLIB::QProjectCore::getCore()->host());
       if(item->text(0).indexOf(text)>=0)
       {
           setSelected(item);
           return;
       }
    }
    find(item,item,text,FP_PREV);
}

void QWidgetView::find(QTreeWidgetItem *start,QTreeWidgetItem *item, const QString &text, FIND_POINT fp)
{
    QTreeWidgetItem *root=m_items.value(SHAREDLIB::QProjectCore::getCore()->host());;
    QTreeWidgetItem *other;
    if(fp==FP_NEXT)
    {
        if(item->childCount()>0)
        {
            other=item->child(0);
        }
        else
        {
            if(item==root)
            {
                return;
            }
            int index;
            other=item;
            do
            {
                index=other->parent()->indexOfChild(other);
                if(index+1<other->parent()->childCount())
                {
                    other=other->parent()->child(index+1);
                    break;
                }
                other=other->parent();
            }while(other!=root);
        }
    }
    else
    {
        if(item!=root)
        {
            int index=item->parent()->indexOfChild(item);
            if(index!=0)
            {
                other=item->parent()->child(index-1);
                while(other->childCount()>0)
                {
                    other=other->child(other->childCount()-1);
                }
            }
            else
            {
                other=item->parent();
            }
        }
        else
        {
            other=item;
            while(other->childCount()>0)
            {
                other=other->child(other->childCount()-1);
            }
        }
    }

    if(other->text(0).indexOf(text)>=0)
    {
        setSelected(other);
        while(1)
        {
            if(other==root)
            {
                break;
            }
            other=other->parent();
            other->setExpanded(true);

        }
    }
    else
    {
        if(other==start)
        {
            return;
        }
        else
        {
            find(start,other,text,fp);
        }
    }
}

void QWidgetView::setSelect(SHAREDLIB::QAbstractHost *host)
{
    QTreeWidgetItem *item=m_items.value(host);
    if(item!=NULL && !item->isSelected())
    {
        this->clearSelection();
        setCurrentItem(item);
        emit select(host);
    }
}

void QWidgetView::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const
{
    QStyleOptionViewItemV3 opt=options;
    QColor c;
    c=QColor(255,191,239);
    painter->fillRect(options.rect,c);
    opt.palette.setColor(QPalette::AlternateBase,c.lighter(112));
    opt.state &=~ QStyle::State_HasFocus;
    QTreeWidget::drawRow(painter,opt,index);
    opt.palette.setCurrentColorGroup(QPalette::Active);

    QColor color=static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor,&opt));
    painter->setPen(color);

    if(index.column()==0)
    {
        int right=options.direction==Qt::LeftToRight?options.rect.right():options.rect.left();
        painter->drawLine(right,options.rect.y(),right,options.rect.bottom());
    }
}

void QWidgetView::setSelected(QTreeWidgetItem *item)
{
    QMapIterator<SHAREDLIB::QAbstractHost*,QTreeWidgetItem*> it(m_items);
    while(it.hasNext())
    {
        it.next();
        if(it.value()==item)
        {
            setSelect(it.key());
            return;
        }
    }
}

SHAREDLIB::QAbstractHost *QWidgetView::currentHost()
{
    QMapIterator<SHAREDLIB::QAbstractHost*,QTreeWidgetItem*>   it(m_items);
    while(it.hasNext())
    {
        it.next();
        if(it.value()->isSelected())
        {
            return it.key();
        }
    }
    return NULL;
}
